package com.bytedance.rangers_applog_flutter_plugin;

import android.content.Context;
import android.os.Handler;
import android.util.Log;

import androidx.annotation.NonNull;

import com.bytedance.applog.AppLog;
import com.bytedance.applog.ILogger;
import com.bytedance.applog.InitConfig;
import com.bytedance.applog.UriConfig;

import org.json.JSONObject;

import java.util.HashMap;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;

/**
 * RangersAppLogFlutterPlugin
 */
public class RangersApplogFlutterPlugin implements FlutterPlugin {
    private MethodChannel channel = null;

    private void setupChannel(BinaryMessenger messenger, Context context) {
        channel = new MethodChannel(messenger, "rangers_applog_flutter_plugin");
        channel.setMethodCallHandler(new AppLogMethodCallHandler(context));
    }

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
        setupChannel(binding.getBinaryMessenger(), binding.getApplicationContext());
        // init EventChannel、DataObserver
        DataObserverManager.init(binding);
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        teardownChannel();
    }

    private void teardownChannel() {
        channel.setMethodCallHandler(null);
        channel = null;
    }

    static class AppLogMethodCallHandler implements MethodCallHandler {

        private static final String TAG = "RangersApplogFlutter";

        private static final String FlutterPluginMethodInitRangersApplog = "initRangersAppLog";
        private static final String FlutterPluginMethodStart = "start";
        private static final String FlutterPluginMethodGetDeviceId = "getDeviceId";
        private static final String FlutterPluginMethodGetAbSdkVersion = "getAbSdkVersion";
        private static final String FlutterPluginMethodGetABTestConfigValueForKey = "getABTestConfigValueForKey";
        private static final String FlutterPluginMethodOnEventV3 = "onEventV3";
        private static final String FlutterPluginMethodSetUserUniqueId = "setUserUniqueId";
        private static final String FlutterPluginMethodSetHeaderInfo = "setHeaderInfo";
        private static final String FlutterPluginMethodProfileSet = "profileSet";
        private static final String FlutterPluginMethodProfileSetOnce = "profileSetOnce";
        private static final String FlutterPluginMethodProfileAppend = "profileAppend";
        private static final String FlutterPluginMethodProfileIncrement = "profileIncrement";
        private static final String FlutterPluginMethodProfileUnset = "profileUnset";
        private static final String FlutterPluginMethodGetAllAbTestConfig = "getAllAbTestConfig";
        private static final String FlutterPluginMethodRemoveHeaderInfo = "removeHeaderInfo";

        private final Context context;

        private AppLogMethodCallHandler(Context context) {
            this.context = context;
        }

        @Override
        public void onMethodCall(MethodCall call, Result result) {
            switch (call.method) {
                case FlutterPluginMethodInitRangersApplog:
                    Log.e(TAG, "appid=" + (String) call.argument("appid") + ", channel=" + (String) call.argument("channel") +
                            ", enableAb=" + (Boolean) call.argument("enable_ab") +
                            ", enable_encrypt=" + (Boolean) call.argument("enable_encrypt") +
                            ", enable_log=" + (Boolean) call.argument("enable_log") +
                            ", host=" + (String) call.argument("host") + ", region=" + (String) call.argument("region") + ", auto_start=" + (Boolean) call.argument("auto_start"));
                    InitConfig initConfig = new InitConfig((String) call.argument("appid"), (String) call.argument("channel"));
                    initConfig.setAutoStart((Boolean) call.argument("auto_start"));
                    initConfig.setAbEnable((Boolean) call.argument("enable_ab"));
                    initConfig.setRegion(call.argument("region"));
                    AppLog.setEncryptAndCompress((Boolean) call.argument("enable_encrypt"));
                    if ((Boolean) call.argument("enable_log")) {
                        initConfig.setLogger(new ILogger() {
                            @Override
                            public void log(String s, Throwable throwable) {
                                Log.d("AppLog------->: ", "" + s);
                            }
                        });
                    }
                    if ((String) call.argument("host") != null) {
                        initConfig.setUriConfig(UriConfig.createByDomain((String) call.argument("host"), null));
                    }
                    AppLog.init(context.getApplicationContext(), initConfig);
                    break;
                case FlutterPluginMethodStart:
                    AppLog.start();
                    break;
                case FlutterPluginMethodGetDeviceId:
                    result.success(AppLog.getDid());
                    break;
                case FlutterPluginMethodGetAbSdkVersion:
                    result.success(AppLog.getAbSdkVersion());
                    break;
                case FlutterPluginMethodGetABTestConfigValueForKey:
                    result.success(AppLog.getAbConfig((String) call.argument("key"), call.argument("default")));
                    break;
                case FlutterPluginMethodOnEventV3:
                    String eventName = (String) call.argument("event");
                    AppLog.onEventV3(eventName, getJsonFromMap(call, "param"));
                    break;
                case FlutterPluginMethodSetUserUniqueId:
                    AppLog.setUserUniqueID((String) call.argument("uuid"));
                    break;
                case FlutterPluginMethodSetHeaderInfo:
                    AppLog.setHeaderInfo((HashMap<String, Object>) call.argument("customHeader"));
                    break;
                case FlutterPluginMethodProfileSet:
                    AppLog.profileSet(getJsonFromMap(call, "profileDict"));
                    break;
                case FlutterPluginMethodProfileSetOnce:
                    AppLog.profileSetOnce(getJsonFromMap(call, "profileDict"));
                    break;
                case FlutterPluginMethodProfileIncrement:
                    AppLog.profileIncrement(getJsonFromMap(call, "profileDict"));
                    break;
                case FlutterPluginMethodProfileAppend:
                    AppLog.profileAppend(getJsonFromMap(call, "profileDict"));
                    break;
                case FlutterPluginMethodProfileUnset:
                    AppLog.profileUnset((String) call.argument("key"));
                    break;
                case FlutterPluginMethodGetAllAbTestConfig:
                    break;
                case FlutterPluginMethodRemoveHeaderInfo:
                    AppLog.removeHeaderInfo((String) call.argument("key"));
                    break;
                default:
                    result.notImplemented();
                    break;
            }
        }

        private JSONObject getJsonFromMap(MethodCall call, String param) {
            try {
                HashMap<String, Object> paramMap = call.argument(param);
                return new JSONObject(paramMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
}
